﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

using LowLevelGraphics.ColorSpaces;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// % BFILTER2 Two dimensional bilateral filtering.
    ///    This function implements 2-D bilateral filtering using
    ///    the method outlined in:
    ///
    ///       C. Tomasi and R. Manduchi. Bilateral Filtering for 
    ///       Gray and Color Images. In Proceedings of the IEEE 
    ///       International Conference on Computer Vision, 1998. 
    ///
    ///    B = bfilter2(A,W,SIGMA) performs 2-D bilateral filtering
    ///    for the grayscale or color image A. A should be a double
    ///    precision matrix of size NxMx1 or NxMx3 (i.e., grayscale
    ///    or color images, respectively) with normalized values in
    ///    the closed interval [0,1]. The half-size of the Gaussian
    ///    bilateral filter window is defined by W. The standard
    ///    deviations of the bilateral filter are given by SIGMA,
    ///    where the spatial-domain standard deviation is given by
    ///    SIGMA(1) and the intensity-domain standard deviation is
    ///    given by SIGMA(2).

    /// </summary>
    public class BFilter2 : BaseImageFilter
    {
        protected bool m_bGrayScale = true;
        protected int m_nWindowSize = 7;
        protected int m_nSigma = 3;

        /// <summary>
        /// 
        /// </summary>
        public BFilter2()
        {
        }

        /// <summary>
        /// Used by cloning
        /// </summary>
        /// <param name="_bfilter2"></param>
        internal BFilter2(BFilter2 _bfilter2)
        {
            m_nSigma = _bfilter2.m_nSigma;
            m_nWindowSize = _bfilter2.m_nWindowSize;
            m_bGrayScale = _bfilter2.m_bGrayScale;
        }

        /// <summary>
        /// sets or gets Sigma
        /// </summary>
        public int Sigma
        {
            get { return m_nSigma; }
            set { m_nSigma = value; }
        }

        /// <summary>
        /// Gets or Sets window size
        /// </summary>
        public int Window
        {
            get { return m_nWindowSize; }
            set { m_nWindowSize = value; }
        }

        /// <summary>
        /// Executes this filter...
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            if (m_bGrayScale)
            {
                return GrayFilter(_bitmap);
            }
            else
            {
                return ColorFilter(_bitmap);
            }
        }

        /// <summary>
        /// Gray Filter
        /// </summary>
        protected virtual UnsafeBitmap GrayFilter(UnsafeBitmap _bitmap)
        {
            int x = 0;
            int y = 0;

            int kx = 0;
            int ky = 0;

            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;

            int iMin = 0;
            int iMax = 0;
            int jMin = 0;
            int jMax = 0;

            // Pre-compute Gaussian domain weights
            int[,] G = new int[m_nWindowSize * 2 + 1, m_nWindowSize * 2 + 1];

            for (y = m_nWindowSize; y < nHeight - m_nWindowSize; y++)
            {
                for (x = m_nWindowSize; x < nWidth - m_nWindowSize; x++)
                {
                    iMin = Math.Max(x - m_nWindowSize, x);
                    iMax = Math.Min(x + m_nWindowSize, x);
                    jMin = Math.Max(y - m_nWindowSize, y);
                    jMax = Math.Min(y + m_nWindowSize, y);

                    for (ky = 0; ky < m_nWindowSize; ky++)
                    {
                        for (kx = 0; kx < m_nWindowSize; kx++)
                        {
                            Color color = _bitmap.GetPixel(x + kx, y + ky);
                            CIELab lab = new CIELab();
                        }
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual UnsafeBitmap ColorFilter(UnsafeBitmap _bitmap)
        {
            return _bitmap;
        }


        /// <summary>
        /// Clones this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new BFilter2(this);
        }
    }
}
